package com.shf.dynamodb;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;

import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMapper;
import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMapperConfig;
import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMapperConfig.ConsistentReads;
import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMapperConfig.DefaultBatchLoadRetryStrategy;
import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMapperConfig.DefaultBatchWriteRetryStrategy;
import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMapperConfig.DefaultTableNameResolver;
import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMapperConfig.PaginationLoadingStrategy;
import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMapperConfig.SaveBehavior;
import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBQueryExpression;
import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBScanExpression;
import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBTypeConverterFactory;
import com.amazonaws.services.dynamodbv2.datamodeling.PaginatedQueryList;
import com.amazonaws.services.dynamodbv2.datamodeling.QueryResultPage;
import com.amazonaws.services.dynamodbv2.datamodeling.ScanResultPage;
import com.amazonaws.services.dynamodbv2.document.DynamoDB;
import com.amazonaws.services.dynamodbv2.document.Table;
import com.amazonaws.services.dynamodbv2.model.AttributeDefinition;
import com.amazonaws.services.dynamodbv2.model.AttributeValue;
import com.amazonaws.services.dynamodbv2.model.CreateTableRequest;
import com.amazonaws.services.dynamodbv2.model.KeySchemaElement;
import com.amazonaws.services.dynamodbv2.model.KeyType;
import com.amazonaws.services.dynamodbv2.model.ProvisionedThroughput;
import com.amazonaws.services.dynamodbv2.model.ScalarAttributeType;
import com.shf.dynamodb.entity.AutoGeneratedKeys;
import com.shf.dynamodb.entity.CatalogItem;
import com.shf.dynamodb.entity.CatalogItem.DimensionType;
import com.shf.dynamodb.entity.ProductCatalogItem;
import com.shf.dynamodb.entity.ProductCatalogItem.Pictures;
import com.shf.dynamodb.util.DynamoDBClientUtil;

public class MapperHighDemo {
	
	/**
	 * 创建表
	 * @param tableName 表名
	 * @param idKeyName hashKeyName
	 * @param idAttrType hashKey类型
	 * @param rangKeyName 排序建名称
	 * @param rangeKeAttrType 排序建类型
	 * @param hasRange 是否有排序建
	 * @param readCapacityUnits  写容量
	 * @param writeCapacityUnits 读容量
	 */
    public static void createTable(String tableName,String idKeyName,ScalarAttributeType idAttrType,String rangKeyName,ScalarAttributeType rangeKeAttrType,
    		boolean hasRange,long readCapacityUnits,long writeCapacityUnits){
    	DynamoDB dynamoDB = new DynamoDB(DynamoDBClientUtil.getDynamoclient());

         List<KeySchemaElement> keyList=null;
         List<AttributeDefinition> attrList=null;
         if(hasRange){
        	 keyList=Arrays.asList(
                     new KeySchemaElement(idKeyName, KeyType.HASH),//Partition key
                     new KeySchemaElement(rangKeyName,KeyType.RANGE)); //sort key
        	 attrList=Arrays.asList(
                     new AttributeDefinition(idKeyName, idAttrType),
                     new AttributeDefinition(rangKeyName,rangeKeAttrType));
         }else{
        	 keyList=Arrays.asList(
                     new KeySchemaElement(idKeyName, KeyType.HASH)); //Partition key
        	 attrList=Arrays.asList(
                     new AttributeDefinition(idKeyName, idAttrType));
         }
         
         try {
        	 
             System.out.println("Attempting to create table; please wait...");
             Table table = dynamoDB.createTable(tableName,
            		 keyList,  
            		 attrList, 
                     new ProvisionedThroughput(readCapacityUnits, writeCapacityUnits));
             table.waitForActive();
             System.out.println("Success.  Table status: " + table.getDescription().getTableStatus());

         } catch (Exception e) {
             System.err.println("Unable to create table: ");
             System.err.println(e.getMessage());
         }finally{
        	 	dynamoDB.shutdown();
         }
    }
	
    /**
     * 保存两个CatalogItem对象
     * @param mapper
     */
	public static void save(DynamoDBMapper mapper){
		CatalogItem item1 = new CatalogItem(102,"Book 102 Title","222-2222222222",
				new HashSet<String>(Arrays.asList("Author 1", "Author 2")),"Test");

		mapper.save(item1);   
		
		CatalogItem item2 = new CatalogItem(103,"Book 103 Title","333-3333333333",
				new HashSet<String>(Arrays.asList("Author 3", "Author 4")),"Test");
		
		mapper.save(item2);   
		System.out.println("----------------保存102、103对象成功----------------");
	}
	
	/**
	 * 查询CatalogItem集合
	 * @param mapper
	 */
	public static void query(DynamoDBMapper mapper){
		CatalogItem partitionKey = new CatalogItem();

		partitionKey.setId(102);
		DynamoDBQueryExpression<CatalogItem> queryExpression = new DynamoDBQueryExpression<CatalogItem>()
		    .withHashKeyValues(partitionKey);

		List<CatalogItem> itemList = mapper.query(CatalogItem.class, queryExpression);

		for (int i = 0; i < itemList.size(); i++) {
		    System.out.println(itemList.get(i).getTitle());
		    System.out.println(itemList.get(i).getBookAuthors());
		}
		
	}
	
	/**
	 * 扫描CatalogItem集合
	 * @param mapper
	 */
	public static void scan(DynamoDBMapper mapper){

		List<CatalogItem> itemList = mapper.scan(CatalogItem.class,new DynamoDBScanExpression());

		for (int i = 0; i < itemList.size(); i++) {
		    System.out.println(itemList.get(i).getTitle());
		    System.out.println(itemList.get(i).getBookAuthors());
		}
		
	}
	
	/**
	 * 保存自动生成ID
	 * @param mapper
	 */
	public static void saveItem(DynamoDBMapper mapper) {
        AutoGeneratedKeys obj = new AutoGeneratedKeys();
        obj.setPayload("abc123");
        
        // id field is null at this point       
        mapper.save(obj);
        
        System.out.println("Object was saved with id " + obj.getId());
	}
	
	/**
	 * 验证内嵌文档对象保存
	 * @param mapper
	 */
	public static void saveDocItem(DynamoDBMapper mapper) {
		ProductCatalogItem item = new ProductCatalogItem();

		Pictures pix = new Pictures();
		pix.setFrontView("http://example.com/products/206_front.jpg");
		pix.setRearView("http://example.com/products/206_rear.jpg");
		pix.setSideView("http://example.com/products/206_left_side.jpg");
		item.setPictures(pix);

		item.setId(123);

		mapper.save(item); 
		
		PaginatedQueryList<ProductCatalogItem> list=mapper.query(ProductCatalogItem.class, 
				new DynamoDBQueryExpression<ProductCatalogItem>().withHashKeyValues(new ProductCatalogItem(123)));
		//遍历查询数据
		list.forEach(productCatalogItem->System.out.print(productCatalogItem.getPictures().toString()));
	}
	
	/**
     * 保存含有新增boolean属性的CatalogItem对象
     * @param mapper
     */
	public static void saveContainsBool(DynamoDBMapper mapper){
		CatalogItem item1 = new CatalogItem(104,"Book 104 Title","44-444444444",
				new HashSet<String>(Arrays.asList("Author 5", "Author 6")),"Test");
		item1.setInStock(true);
		mapper.save(item1);   
		//查询出来显示
		PaginatedQueryList<CatalogItem> list=mapper.query(CatalogItem.class, 
				new DynamoDBQueryExpression<CatalogItem>().withHashKeyValues(new CatalogItem(104)));
		list.forEach(item->System.out.println("inStock:"+item.getInStock()+"Author:"+item.getBookAuthors()));
	}
	
	/**
	 * load方法应用
	 * @param mapper
	 */
	public static void loadCatalogItem(DynamoDBMapper mapper){
		CatalogItem item=mapper.load(CatalogItem.class, 104,ConsistentReads.CONSISTENT.config());
		System.out.println("inStock:"+item.getInStock()+"\nAuthor:"+item.getBookAuthors());
	}
	
	/**
	 * 查询全局二级索引
	 * @param mapper
	 */
	public static void queryByIndex(DynamoDBMapper mapper){
		HashMap<String, AttributeValue> eav = new HashMap<String, AttributeValue>();
		eav.put(":v1",  new AttributeValue().withN("104"));
		eav.put(":v2",  new AttributeValue().withS("Book"));

		DynamoDBQueryExpression<CatalogItem> queryExpression = new DynamoDBQueryExpression<CatalogItem>()
		    .withIndexName("id-title-Index")
		    .withConsistentRead(false)//由于全局二级索引支持最终一致性读取，但不支持强一致性读取，因此我们必须指定 withConsistentRead(false)
		    .withKeyConditionExpression("Id = :v1 and begins_with(Title, :v2)")
		    .withExpressionAttributeValues(eav);

		List<CatalogItem> list =  mapper.query(CatalogItem.class, queryExpression);
		list.forEach(item->System.out.println("id:"+item.getId()+";Title:"+item.getTitle()));
	}
	
	/**
     * 分页查询(带条件、显示列)
     * @param mapper
     */
	public static void queryPage(DynamoDBMapper mapper){
		HashMap<String, AttributeValue> eav = new HashMap<String, AttributeValue>();
		eav.put(":v1",  new AttributeValue().withN("104"));

		DynamoDBQueryExpression<CatalogItem> queryExpression = new DynamoDBQueryExpression<CatalogItem>()
		    .withKeyConditionExpression("Id = :v1")//query必须制定key条件
		    .withExpressionAttributeValues(eav)//对key条件设置属性值
		    .withProjectionExpression("Id,InStock");//设定显示属性，此时Author为null
		
		QueryResultPage<CatalogItem> page=mapper.queryPage(CatalogItem.class, queryExpression);
		List<CatalogItem> list =page.getResults();
		list.forEach(item->System.out.println("inStock:"+item.getInStock()+";Author:"+item.getBookAuthors()));
	}
	
	/**
     * 分页扫描(带条件、显示列)
     * @param mapper
     */
	public static void scanPage(DynamoDBMapper mapper){
		HashMap<String, AttributeValue> eav = new HashMap<String, AttributeValue>();
		eav.put(":v1",  new AttributeValue().withS("Book"));

		DynamoDBScanExpression scanExpression = new DynamoDBScanExpression()
		    .withFilterExpression(("begins_with(Title, :v1)"))//scan设定过滤条件
		    .withExpressionAttributeValues(eav)//对key条件设置属性值
		    .withProjectionExpression("Id,Title");//设定显示属性，此时Author为null
		
		ScanResultPage<CatalogItem> page=mapper.scanPage(CatalogItem.class, scanExpression);
		List<CatalogItem> list =page.getResults();
		list.forEach(item->System.out.println("Id:"+item.getId()+";Title:"+item.getTitle()+";Author:"+item.getBookAuthors()));
	}
	
	
	/**
     * 并行扫描(带条件、显示列)
     * @param mapper
     */
	public static void parallelScan(DynamoDBMapper mapper){
		int numberOfThreads = 4;
		
		HashMap<String, AttributeValue> eav = new HashMap<String, AttributeValue>();
		eav.put(":v1",  new AttributeValue().withS("Book"));

		DynamoDBScanExpression scanExpression = new DynamoDBScanExpression()
		    .withFilterExpression(("begins_with(Title, :v1)"))//scan设定过滤条件
		    .withExpressionAttributeValues(eav)//对key条件设置属性值
		    .withProjectionExpression("Id,Title");//设定显示属性，此时Author为null
		
		List<CatalogItem> list =mapper.parallelScan(CatalogItem.class, scanExpression, numberOfThreads);
		list.forEach(item->System.out.println("Id:"+item.getId()+";Title:"+item.getTitle()+";Author:"+item.getBookAuthors()));

	}
	
	/**
     * 批量保存
     * @param mapper
     */
	public static void batchSave(DynamoDBMapper mapper){
		CatalogItem item1 = new CatalogItem(105,"Book 105 Title","55-5555555555555",
				new HashSet<String>(Arrays.asList("Author 15", "Author 25")),"Test");
		CatalogItem item2 = new CatalogItem(106,"Book 106 Title","5555-6666666",
				new HashSet<String>(Arrays.asList("Author 36", "Author 46")),"Test");
		mapper.batchSave(item1,item2);   
		System.out.println("----------------保存105、106对象成功----------------");
	}
	
	
	/**
     * 批量load
     * @param mapper
     */
	public static void batchLoad(DynamoDBMapper mapper){
		ArrayList<Object> itemsToGet = new ArrayList<Object>();

		CatalogItem catalogItem = new CatalogItem(106);
		itemsToGet.add(catalogItem);

		ProductCatalogItem productCatalogItem = new ProductCatalogItem(123);
		itemsToGet.add(productCatalogItem);

		Map<String, List<Object>> items = mapper.batchLoad(itemsToGet);
		for (Map.Entry<String,List<Object>> item : items.entrySet()) {
			item.getValue().forEach(data->System.out.println(data.toString()));
		}
	}
	
	/**
     * 批量删除
     * @param mapper
     */
	public static void batchDelete(DynamoDBMapper mapper){
		System.out.println("删除前扫描");
		parallelScan(mapper);
		CatalogItem item1 = new CatalogItem(105);
		CatalogItem item2 = new CatalogItem(106);
		mapper.batchDelete(Arrays.asList(item1,item2)); 
		System.out.println("删除后扫描");
		parallelScan(mapper);
	}
	
	/**
     * 批量Write
     * @param mapper
     */
	public static void batchWrite(DynamoDBMapper mapper){
		System.out.println("删除前扫描ProductCatalog表");
		parallelScan(mapper);
		//新增写入ProductCatalog表
		CatalogItem item1 = new CatalogItem(107,"Book 107 Title","777-77777777",
				new HashSet<String>(Arrays.asList("Author 17", "Author 27")),"Test8");
		CatalogItem item2 = new CatalogItem(108,"Book 108 Title","8888-88888888888",
				new HashSet<String>(Arrays.asList("Author 38", "Author 48")),"Test8");

		//新增写入
		ProductCatalogItem productCatalogItem = new ProductCatalogItem(146);
		Pictures pix = new Pictures();
		pix.setFrontView("http://example.com/products/206_front.jpg");
		pix.setRearView("http://example.com/products/206_rear.jpg");
		pix.setSideView("http://example.com/products/206_left_side.jpg");
		productCatalogItem.setPictures(pix);
		
		// 加载一个ProductCatalogItem然后删除他
		ProductCatalogItem productCatalogItem2 = new ProductCatalogItem(123);
		
		List<Object> objectsToWrite = Arrays.asList(item1, item2,productCatalogItem);
		List<ProductCatalogItem> objectsToDelete = Arrays.asList(productCatalogItem2); 
		
		mapper.batchWrite(objectsToWrite, objectsToDelete);
		System.out.println("删除后扫描ProductCatalog表");
		parallelScan(mapper);
	}
	
	/**
	 * 评估指定的扫描表达式并返回匹配项目的数量
	 * @param mapper
	 */
	public static void count(DynamoDBMapper mapper){
		HashMap<String, AttributeValue> eav = new HashMap<String, AttributeValue>();
		eav.put(":v1",  new AttributeValue().withS("Book"));

		DynamoDBScanExpression scanExpression = new DynamoDBScanExpression()
		    .withFilterExpression(("begins_with(Title, :v1)"))//scan设定过滤条件
		    .withExpressionAttributeValues(eav);//对key条件设置属性值
		
		int count=mapper.count(CatalogItem.class, scanExpression);
		System.out.println("CatalogItem对象对应的ProductCatalog表中存有"+count+"个数据");
	}
	
	/**
	 * 分析代表 DynamoDB 表的 POJO 类，并返回针对该表的 CreateTableRequest。
	 * @param mapper
	 */
	public static void generateCreateTableRequest(DynamoDBMapper mapper){
		CreateTableRequest createTableRequest=mapper.generateCreateTableRequest(CatalogItem.class);
		System.out.println("实体类CatalogItem对应的表名"+createTableRequest.getTableName()+"；readLimit："+createTableRequest.getReadLimit());
	}
	
	/**
	 * 自定义配置
	 * ConsistentReads 枚举值：
	 * 		EVENTUAL - 此映射器实例使用最终一致性读取请求。
	 * 		CONSISTENT - 此映射器实例使用强一致性读取请求。您可以将此可选设置用于 load、query 或 scan 操作。强一致性读取会影响性能和成本；
	 * 		如果您未指定适用于映射器实例的读取一致性设置，则默认为 EVENTUAL。
	 * PaginationLoadingStrategy 枚举值 - 控制映射器实例如何处理分页数据列表（如，来自 query 或 scan的结果）：
	 * 		LAZY_LOADING - 该映射器实例在可能时加载数据，并将所有加载的结果保留在内存中。
	 * 		EAGER_LOADING - 该映射器实例在列表初始化之后立即加载数据。
	 * 		ITERATION_ONLY - 您只能使用 Iterator 从列表读取。在迭代过程中，该列表会在加载下一页之前清除所有之前的结果，这样该列表就会将至多一页加载的结果保留在内存中。这也意味着只能对该列表迭代一次。当处理较大的项目时，为了减少内存开销，建议采用这种策略。
	 * 		如果您不为映射器实例指定分页加载策略，则会默认为 LAZY_LOADING。
	 * SaveBehavior 枚举值 – 指定映射器实例在保存操作期间如何处理属性：
	 * 		UPDATE - 在保存操作期间，所有已建模的属性都将更新，未建模的属性不受影响。基元数字类型（byte、int 和 long）设置为 0。数据元类型设置为空。
	 * 		CLOBBER - 清除并替换保存操作期间的所有属性，包括未建模的属性。这是通过删除并重新创建项目完成的。受版本控制的字段约束也将被忽略。
	 * 		如果您未指定适用于映射器实例的保存行为，则会默认为 UPDATE。
	 * TableNameOverride 对象 - 指示映射器实例忽略由类的 DynamoDBTable 注释指定的表名称，改为使用您提供的不同表名称。当您在运行时将数据划分到多个表中时，可以使用此数据元。
	 * @return
	 */
	public static DynamoDBMapperConfig customizDynamoDBMapperConfig(){
		return DynamoDBMapperConfig.builder()
				.withSaveBehavior(SaveBehavior.UPDATE)
				.withConsistentReads(ConsistentReads.CONSISTENT)
		        .withPaginationLoadingStrategy(PaginationLoadingStrategy.LAZY_LOADING)
		        .withTableNameResolver(DefaultTableNameResolver.INSTANCE)
		        .withBatchWriteRetryStrategy(DefaultBatchWriteRetryStrategy.INSTANCE)
		        .withBatchLoadRetryStrategy(DefaultBatchLoadRetryStrategy.INSTANCE)
		        .withTypeConverterFactory(DynamoDBTypeConverterFactory.standard())
		        .build();
	}
	
	/**
	 * 乐观锁版本号应用
	 *    1、通过在DynamoDBMapper中设定了启用乐观锁控制检查；--异常不能更新
	 *    2、对当前特定save操作取消乐观锁控制检查；--能够更新
	 * @param mapper
	 */
	public static void saveHasOptimisticLock(DynamoDBMapper mapper){
		CatalogItem item1=mapper.load(CatalogItem.class, 104);
		System.out.println("首次查询104数据：Id:"+item1.getId()+"\nVersion:"+item1.getVersion());
		
		CatalogItem item2=mapper.load(CatalogItem.class, 104);
		mapper.save(item2);
		System.out.println("更新后的104数据:"+item2.getId()+"\nVersion:"+item2.getVersion());
		
		System.out.println("在DynamoDBMapper中设定了启用乐观锁控制检查--启用乐观锁");
		try{
			mapper.save(item1);
			System.out.println("更新后的104数据:"+item1.getId()+"\nVersion:"+item1.getVersion());
		}catch (Exception e) {
			System.out.println("由于乐观锁版本不匹配更新失败");
		}
		
		System.out.println("在特定save方法中取消乐观锁控制检查--禁用乐观锁");
		try{
			mapper.save(item1,SaveBehavior.CLOBBER.config());
			System.out.println("更新后的104数据:"+item1.getId()+"\nVersion:"+item1.getVersion());
		}catch (Exception e) {
			System.out.println("由于乐观锁版本不匹配更新失败");
		}
	}
	
	/**
	 * 验证映射任意数据，通过实现DynamoDBTypeConverter接口自定义类型装换器
	 * @param mapper
	 */
	public static void custizConverter(DynamoDBMapper mapper){
		try{
			CatalogItem item1=mapper.load(CatalogItem.class, 104);
			DimensionType dimensionType = new DimensionType();
			dimensionType.setHeight("8.00");
			dimensionType.setLength("11.0");
			dimensionType.setThickness("1.0");
	        item1.setDimensions(dimensionType);
	        
			mapper.save(item1);
			
			CatalogItem itemRetrieved=mapper.load(CatalogItem.class, 104);
			System.out.println("CatalogItem 104 info:"+"\n"+itemRetrieved.toString());
			
			itemRetrieved.getDimensions().setHeight("9.0");
			itemRetrieved.getDimensions().setLength("12.0");
			itemRetrieved.getDimensions().setThickness("2.0");
	        
	        mapper.save(itemRetrieved);

	        itemRetrieved = mapper.load(CatalogItem.class, 104);    
	        System.out.println("Updated CatalogItem 104 info: " + "\n" + itemRetrieved);
			
		}catch (Exception e) {
			System.out.println("由于乐观锁版本不匹配更新失败");
		}
	}
	
	public static void main(String[] args) {
		
//		DynamoDBMapper mapper = new DynamoDBMapper(DynamoDBClientUtil.getDynamoclient());
		
		//添加自定义可选配置
		DynamoDBMapper mapper = new DynamoDBMapper(DynamoDBClientUtil.getDynamoclient(),customizDynamoDBMapperConfig());
		
		//验证对象化操作
//		System.out.println("----------------创建ProductCatalog表----------------") ;
////		createTable("ProductCatalog","Id",ScalarAttributeType.N,null,null,false,10,10);
//		System.out.println("----------------保存CatalogItem对象----------------");
//		save(mapper);
//		System.out.println("----------------查询ID102的CatalogItem对象----------------");
//		query(mapper);
//		System.out.println("----------------扫描ProductCatalog（CatalogItem）全表----------------");
//		scan(mapper);
		
		//验证自动生成主键--注解@DynamoDBAutoGeneratedKey
//		System.out.println("----------------创建AutoGeneratedKeysExample表----------------");
//		createTable("AutoGeneratedKeysExample","Id",ScalarAttributeType.S,null,null,false,10,10);
//		System.out.println("----------------保存AutoGeneratedKeys对象----------------");
//		saveItem(mapper);
		
		//验证DyanamoDB文档操作--注解@DynamoDBDocument
//		System.out.println("----------------创建ProductCatalogItem表----------------");
//		createTable("ProductCatalogItem","Id",ScalarAttributeType.N,null,null,false,10,10);
//		System.out.println("----------------保存内嵌Picture文档的ProductCatalogItem实体对象----------------");
//		saveDocItem(mapper);
		
//		System.out.println("----------------保存含有新增boolean属性的CatalogItem对象----------------");
//		saveContainsBool(mapper);
//		System.out.println("----------------load方法应用----------------");
//		loadCatalogItem(mapper);
		
//		System.out.println("----------------查询全局二级索引----------------");
//		queryByIndex(mapper);
		
//		System.out.println("----------------分页查询(带条件、显示列)----------------");
//		queryPage(mapper);
//		System.out.println("----------------分页扫描(带条件、显示列)----------------");
//		scanPage(mapper);
//		System.out.println("----------------多线程并行扫描（带条件、显示列）----------------");
//		parallelScan(mapper);
		
//		System.out.println("----------------批量保存----------------");
//		batchSave(mapper);
//		System.out.println("----------------批量load----------------");
//		batchLoad(mapper);
//		System.out.println("----------------批量删除----------------");
//		batchDelete(mapper);
//		System.out.println("----------------批量Write----------------");
//		batchWrite(mapper);
		
//		System.out.println("----------------评估指定的扫描表达式并返回匹配项目的数量----------------");
//		count(mapper);
		
//		System.out.println("----------------分析代表 DynamoDB 表的 CatalogItem类---------------");
//		generateCreateTableRequest(mapper);
		
//		System.out.println("----------------乐观锁版本号应用---------------");
//		saveHasOptimisticLock(mapper);
		
		System.out.println("----------------验证映射任意数据，通过实现DynamoDBTypeConverter接口自定义类型装换器---------------");
		custizConverter(mapper);
		
	}
}
